package com.smartrm.trade.domain;

import com.google.common.collect.Lists;
import com.smartrm.globalinfrcore.api.CommonError;
import com.smartrm.globalinfrcore.event.DomainEventBus;
import com.smartrm.globalinfrcore.exception.DomainException;
import com.smartrm.trade.domain.event.OrderSuccessedEvent;
import com.smartrm.trade.domain.valueobject.StockedCommodityVOJ;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;

/*
 * @program: common-starters
 * @description: 订单实体
 * @author: houhong
 * @create: 2023-01-10 16:03
 */
public class OrderDO {

    /*
     * 聚合根
     */
    private long machineId;
    /*
     * 订单实体唯一标识
     */
    private long orderId;
    /*
     * 支付id
     */
    private long paymentId;
    /*
     * 订单实体状态
     */
    private OrderState orderState;

    private OrderType type;
    /*
     * 订单的商品列表
     */
    List<StockedCommodityVOJ> commodities;

    private DomainEventBus eventBus;

    private OrderDO() {

    }

    public BigDecimal totalAmount() {
        BigDecimal ret = new BigDecimal(0);
        for (StockedCommodityVOJ commodity : commodities) {
            ret = ret.add(commodity.getPrice().multiply(new BigDecimal(commodity.getCount())));
        }
        return ret;
    }

    /*
     * 完成订单
     */
    public void successed() {
        orderState = OrderState.Success;
        //订单完成 领域事件
        eventBus.post(new OrderSuccessedEvent(this));
    }

    public long getMachineId() {
        return machineId;
    }

    public void setMachineId(long machineId) {
        this.machineId = machineId;
    }

    public long getOrderId() {
        return orderId;
    }

    public void setOrderId(long orderId) {
        this.orderId = orderId;
    }

    public long getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(long paymentId) {
        this.paymentId = paymentId;
    }

    public OrderState getOrderState() {
        return orderState;
    }

    public void setOrderState(OrderState orderState) {
        this.orderState = orderState;
    }

    public OrderType getType() {
        return type;
    }

    public void setType(OrderType type) {
        this.type = type;
    }

    public List<StockedCommodityVOJ> getCommodities() {
        return commodities;
    }

    public void setCommodities(List<StockedCommodityVOJ> commodities) {
        this.commodities = commodities;
    }

    public DomainEventBus getEventBus() {
        return eventBus;
    }

    public void setEventBus(DomainEventBus eventBus) {
        this.eventBus = eventBus;
    }

    public static OrderDO.Builder Builder() {
        return new OrderDO.Builder();
    }

    public static class Builder {

        private long orderId;
        private long machineId;
        private long paymentId;
        private OrderState state;
        private OrderType type;
        private Collection<StockedCommodityVOJ> commodities;
        private DomainEventBus eventBus;

        public Builder orderId(long orderId) {
            this.orderId = orderId;
            return this;
        }

        public Builder machineId(long machineId) {
            this.machineId = machineId;
            return this;
        }

        public Builder paymentId(long paymentId) {
            this.paymentId = paymentId;
            return this;
        }

        public Builder state(OrderState state) {
            this.state = state;
            return this;
        }

        public Builder commodities(Collection<StockedCommodityVOJ> commodities) {
            this.commodities = Lists.newArrayList(commodities);
            return this;
        }

        public Builder type(OrderType type) {
            this.type = type;
            return this;
        }

        public Builder eventBus(DomainEventBus eventBus) {
            this.eventBus = eventBus;
            return this;
        }

        public OrderDO build() {
            if (machineId == 0 || state == null || type == null) {
                throw new DomainException(CommonError.InvalidProperty);
            }
            OrderDO order = new OrderDO();
            order.orderId = this.orderId;
            order.type = this.type;
            order.machineId = this.machineId;
            order.paymentId = this.paymentId;
            order.orderState = this.state;
            order.commodities = Lists.newArrayList(this.commodities);
            order.eventBus = eventBus;
            return order;
        }


    }
}